ArmSort
=======
The ArmSort module, written and  by Martin Avison, is used with his permission by this application to sort data in BASIC Arrays quickly and easily. ArmSort will sort any number of any type of BASIC array with just a '*Sort Array()' command in your program, and has many other sorting options.

Further details and the latest version of the full !ArmSort package and documentation is available from http://www.avisoft.f9.co.uk/.

Copyright
---------
This application is copyright  C.K.Hall 2012.

'!Help' for CountDn ver 0.24
----------------------------
The original version of this programme, bundled with the Raspberry Pi SD card image, was
a simple single-tasking one that used BASIC to calculate the solution (mostly correctly) 
with a fairly basic user interface to select one of ten scenarios or to input a selection 
of tiles and target. The solution took about 30s and the logic was not perfect.

This multi-tasking version has been rewritten with the time-critical bit in assembler so
that the calculation time (to work out how many of the 900 possible targets from 100 to 999
are feasible and, for each, how many different ways they can be solved) has reduced to
about 30cs. It now offers a better graphical interface to select either random tiles (with
them face down) or specific tiles (with them face up). 

Once all six tiles have been chosen it shows a 'difficulty spectrum' for the chosen tiles.

Clicking on this spectrum allows the level of difficulty to be chosen ranging from easy on
the left to difficult and impossible on the right. A simpler choise of an Easy,
Difficult or (where some targets are not possible) Impossible target number can also
be made by clicking over the relevant button. This choice by button
can be repeated or a specific target chosen from a menu. Although the computer knows the
solution, this is only displayed when you click 'Reveal'. Further clicks on 'Reveal' using
the ADJUST button will show different solutions up to 1000 different solutions are stored).
The interactive '!Help' application offers pop-up help throughout.

Click the icon bar icon to open the window and start the game.

Some more unusual games are listed below:
Tiles 3, 6, 25, 50 ,75, 100 with a target of 952 (large intermediate results)

The solving logic is written in assembler in lines 19700 to 21860 and stores the result
(the method of calculation) in three 32 bit words representing each parameter or operation
as a 4-bit item in reverse Polish logic - for example (reading from the high end to the 
low end) 893AB12 CD4 5 would mean LHS is tile 1(8) tile 2(9) reverse minus(3) tile 3(A)
tile 4(B) plus(1) minus(2) RHS is tile 5(C) tile 6(D) divide(4) and the operator is
reverse divide (5). The other operator (not used here) is multiply(6). In algenbraic
notation this would be:

solution =   t5/t6
            ---------------
            (t2-t1)-(t3+t4)

Slightly more complicated than this is where all six tiles are used and the RHS is a single
tile - in this case the first term in the LHS has to be inferred as the only otherwsie
unused tile.

For example AB1CD2933 would be expressed as B1CD2933 with the leading A inferred from the
contents of the RHS - here this would be 8.

The equivalent BASIC for the assembler used in the programme is as follows:
   10 DIM a%(6) , a$(6) , res%(999) , res$(999)
   20 REM Chosen tiles are a%,b%,c%,d%,e%,f% in ascending order
   30 a%(1)=a%:a$(1)=STR$(a%)
   40 a%(2)=b%:a$(2)=STR$(b%)
   50 a%(3)=c%:a$(3)=STR$(c%)
   60 a%(4)=d%:a$(4)=STR$(d%)
   70 a%(5)=e%:a$(5)=STR$(e%)
   80 a%(6)=f%:a$(6)=STR$(f%)
   90 res%()=0
  100 res$()=""
  110 rs%=0
  120 numbers%=6
  130 td%=TIME
  140 IF a%(6)=100 THEN res$(100)="100":res%(100)=1
  150 PROCrecurse
  160 td%=TIME-td%
  170 i%=0
  180 PRINT "Calculation took ";td%;"cs"
  190 IF res%(r%) THEN
  200   PRINT "Exact match ";r%;"=";res$(r%)
  210 ELSE
  220   i%=0
  230   REPEAT
  240     i%+=1
  250     IF res%(r%+i%) THEN
  260       PRINT "Closest match ";r%+i%;"="res$(r%+i%)
  270     ELSE
  280       IF res%(r%-i%) THEN PRINT "Closest match ";r%-i%;"="res$(r%-i%)
  290     ENDIF
  300   UNTIL res%(r%+i%) OR res%(r%-i%) OR i%>9
  310   IF res%(r%+i%)=0 AND res%(r%-i%)=0 THEN PRINT "No close match"
  320 ENDIF
  330 PRINT rs%;" different results 100..999"
  340 PRINT "leaving the following impossible:"
  350 FOR i%=100 TO 999
  360   IF res%(i%)=0 THEN PRINT ;i%;"  ";
  370 NEXT i%
  380 END
  390 :
  400 DEFPROCrecurse
  410 LOCAL i%,j%,o%,k%,ni%,nj%,ni$,nj$
  420 result%=0
  430 result$=""
  440 FOR i%=1 TO numbers%-1
  450   ni%=a%(i%)
  460   ni$=a$(i%)
  470   FOR j%=i%+1 TO numbers%
  480     nj%=a%(j%)
  490     nj$=a$(j%)
  500     k%=j%
  510     WHILE k%<numbers%
  520       a%(k%)=a%(k%+1)
  530       a$(k%)=a$(k%+1)
  540       k%+=1
  550     ENDWHILE
  560     numbers%-=1
  570     o%=1
  580     REPEAT
  590       IF o%=2 AND nj%>ni% THEN o%+=1
  600       IF o%=3 AND ni%>nj% THEN o%+=1
  610       IF o%=4 AND nj%=0 THEN o%+=1
  620       IF o%=4 THEN IF (ni% MOD nj%)<>0 THEN o%+=1
  630       IF o%=5 AND ni%=0 THEN o%+=1
  640       IF o%=5 THEN IF (nj% MOD ni%)<>0 THEN o%+=1
  650       PROCcalc(o%,ni%,nj%,ni$,nj$,result%,result$)
  660       a%(i%)=result%
  670       a$(i%)=result$
  680       IF result%>99 AND result%<1000 THEN
  690         IF res%(result%)=0 THEN res$(result%)=result$:rs%+=1
  700         res%(result%)+=1
  710       ENDIF
  720       IF numbers%>1 THEN PROCrecurse
  730       o%+=1
  740     UNTIL o%>6
  750     k%=numbers%
  760     WHILE k%>j%
  770       a%(k%)=a%(k%-1)
  780       a$(k%)=a$(k%-1)
  790       k%-=1
  800     ENDWHILE
  810     numbers%+=1
  820     a%(j%)=nj%
  830     a$(j%)=nj$
  840   NEXT j%
  850   a%(i%)=ni%
  860   a$(i%)=ni$
  870 NEXT i%
  880 ENDPROC
  890 :
  900 DEFPROCcalc(x%,y%,z%,y$,z$,RETURN r%,RETURN r$)
  910 CASE x% OF
  920   WHEN 1
  930     r%=y%+z%
  940     r$=y$+z$+"+"
  950     r$="("+y$+"+"+z$+")"
  960   WHEN 2
  970     r%=y%-z%
  980     r$=y$+z$+"-"
  990     r$="("+y$+"-"+z$+")"
 1000   WHEN 3
 1010     r%=z%-y%
 1020     r$=z$+y$+"-"
 1030     r$="("+z$+"-"+y$+")"
 1040   WHEN 4
 1050     r%=y%/z%
 1060     r$=y$+z$+"/"
 1070     r$="("+y$+"/"+z$+")"
 1080   WHEN 5
 1090     r%=z%/y%
 1100     r$=z$+y$+"/"
 1110     r$="("+z$+"/"+y$+")"
 1120   WHEN 6
 1130     r%=y%*z%
 1140     r$=y$+z$+"*"
 1150     r$="("+y$+"*"+z$+")"
 1160 ENDCASE
 1170 ENDPROC
